package org.cook.utils.common;

import java.io.File;
import java.io.IOException;
import java.net.URISyntaxException;
import java.net.URL;
import java.net.URLDecoder;
import java.util.Enumeration;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import net.sourceforge.pinyin4j.PinyinHelper;


public final class Utils {

	private static final String HEX_ALPH = "0123456789ABCDEF";
	
	public static boolean isMatched(String text, String regex) {
		Pattern p = Pattern.compile(regex);
		Matcher m = p.matcher(text);
		return m.find();
	}
	
	public static String replaceAll(String s, String regex, String replacement) {
		if (s == null) {
			return "";
		}
		Pattern p = Pattern.compile(regex);
		
		Matcher m = p.matcher(s);
		
		StringBuffer sb = new StringBuffer();
		while (m.find()) {
			m.appendReplacement(sb, replacement);
		}
		m.appendTail(sb);
		
		return sb.toString();
	}
	
	public static String extractMatched(String line, String regex, int group) {
		Matcher m = Pattern.compile(regex).matcher(line);
		return m.find() ? m.group(group) : null;
	}
	
	public static boolean isEmpty(String text) {
		return text == null || text.trim().length() == 0;
	}
	
	public static boolean isNotEmpty(String text) {
		return !isEmpty(text);
	}
	
	public static boolean isEmpty(List<?> list) {
		return list == null || list.isEmpty();
	}
	
	public static boolean isNotEmpty(List<?> list) {
		return !isEmpty(list);
	}
	
	public static String charToPinyin(char c) {
		String[] pinyins = PinyinHelper.toHanyuPinyinStringArray(c);
		if (pinyins == null) {// 如果转换结果为空，则返回null
			return "";
		}
		return pinyins[0]; // 如果为多音字返回第一个音节
	}
	
	public static String stringToPinyin(String s) {
		if (isEmpty(s)) return "";
		
		StringBuilder pinyin = new StringBuilder();
		for (char c : s.toCharArray()) {
			pinyin.append(charToPinyin(c));
		}
		return pinyin.toString();
	}


	/**
	 * A methord for Simple Chinese Lanuage to Unicode
	 * 
	 * @param s Simple Chinese Lanuage
	 * @return s1 Unicode
	 */
	public static String toUnicode(String s) {
		StringBuilder sb = new StringBuilder();
		for (char c : s.toCharArray()) {
			sb.append("\\u").append(Integer.toHexString(c & 0xffff));
		}
		return sb.toString();
	}

	public static int byteToInt(byte b) {
		return Integer.valueOf(byteToHex(b), 16).intValue();
	}
	
	public static String byteToHex(byte b) {
		return new StringBuilder(2).append(HEX_ALPH.charAt(b >> 4 & 0xF)).append(HEX_ALPH.charAt(b & 0xF)).toString();
	}
	
	/**
	   * List directory contents for a resource folder. Not recursive.
	   * This is basically a brute-force implementation.
	   * Works for regular files and also JARs.
	   * 
	   * @author Greg Briggs
	   * @param clazz Any java class that lives in the same place as the resources you want.
	   * @param path Should end with "/", but not start with one.
	   * @return Just the name of each member item, not the full paths.
	   * @throws URISyntaxException 
	   * @throws IOException 
	   */
	String[] getResourceListing(Class<?> clazz, String path) throws URISyntaxException, IOException {
		URL dirURL = clazz.getClassLoader().getResource(path);
		if (dirURL != null && dirURL.getProtocol().equals("file")) {/* A file path: easy enough */
			return new File(dirURL.toURI()).list();
		}

		if (dirURL == null) {// In case of a jar file, we can't actually find a directory. Have to assume the same jar as clazz.
			String me = clazz.getName().replace(".", "/") + ".class";
			dirURL = clazz.getClassLoader().getResource(me);
		}

		if (dirURL.getProtocol().equals("jar")) {/* A JAR path */

			String jarPath = dirURL.getPath().substring(5, dirURL.getPath().indexOf("!")); // strip out only the JAR file
			JarFile jar = new JarFile(URLDecoder.decode(jarPath, "UTF-8"));
			Enumeration<JarEntry> entries = jar.entries(); // gives ALL entries in jar
			Set<String> result = new HashSet<String>(); // avoid duplicates in case it is a subdirectory
			while (entries.hasMoreElements()) {
				String name = entries.nextElement().getName();
				if (name.startsWith(path)) { // filter according to the path
					String entry = name.substring(path.length());
					int checkSubdir = entry.indexOf("/");
					if (checkSubdir >= 0) {
						// if it is a subdirectory, we just return the directory name
						entry = entry.substring(0, checkSubdir);
					}
					result.add(entry);
				}
			}
			return result.toArray(new String[result.size()]);
		}

		throw new UnsupportedOperationException("Cannot list files for URL " + dirURL);
	}
	
	public static String byteToChar(byte[] bs) {
		if (bs == null || bs.length == 0) {
			return "";
		}
		StringBuilder text = new StringBuilder(bs.length);
		for (byte b : bs) {
			text.append((char) byteToInt(b));
		}
		
		return text.toString();
	}

}
